/*
 * MIT License
 *
 * Copyright (c) 2023-present, tangli
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

@file:JvmName("DataScopes")

package tony.mybatis.datascope.model

/**
 * 数据权限相关变量常量
 * @author tangli
 * @date 2025/09/15 12:44
 */

/**
 * Data scope context
 */
internal val current = ScopedValue.newInstance<DataScopeValue>()

/**
 * Data scope context value
 *
 * @property userIdList
 * @property orgIdList
 * @property userIdColumn
 * @property orgIdColumn
 * @property scopedColumns
 * @constructor Create empty Data scope context value
 */
public data class DataScopeValue(
    /**
     * 用户id列表
     */
    val userIdList: Collection<String>,
    /**
     * 组织id列表
     */
    val orgIdList: Collection<String>,
    /**
     * 要处理的表
     */
    val tables: Collection<ScopedTable>,
    /**
     * 用户id列名称.
     * 默认 `creator_id`
     */
    val userIdColumn: String,
    /**
     * 组织id列名称.
     * 默认 `creator_org_id`
     */
    val orgIdColumn: String,
    /**
     * 自定义 [userIdColumn], [orgIdColumn].
     * 根据 [ScopedColumn.tableAlias] 匹配.
     */
    val scopedColumns: Collection<ScopedColumn> = emptyList(),
    /**
     * [tables]的选择类型.
     *
     * 是 包含[SelectionType.INCLUDE] , 还是排除 [SelectionType.EXCLUDE]
     */
    val selectionType: SelectionType = SelectionType.EXCLUDE,
) {
    /**
     * 要处理的表名, 过滤 [tables] 里 所有 [ScopedTable.nameType] 为 [TableNameType.TABLE]的数据.
     */
    val tableNames: Collection<String> = tables.filter { it.nameType == TableNameType.TABLE }.map { it.name }.toSet()

    /**
     * 要处理的表别名, 过滤 [tables] 里 所有 [ScopedTable.nameType] 为 [TableNameType.ALIAS]的数据.
     */
    val tableAliases: Collection<String> = tables.filter { it.nameType == TableNameType.ALIAS }.map { it.name }.toSet()
}

/**
 * 数据权限自定义对应表名.
 * 根据sql 的表别名对应.
 *
 * @property name 表名
 * @property nameType 表名类型
 */
public data class ScopedTable
    @JvmOverloads
    constructor(
        val name: String,
        val nameType: TableNameType = TableNameType.TABLE,
    )

/**
 * 数据权限自定义对应字段名.
 * 根据sql 的表别名对应.
 *
 * @property tableAlias 表别名
 * @property userIdColumn 用户id列名称.
 * @property orgIdColumn 组织id列名称.
 */
public data class ScopedColumn
    internal constructor(
        val tableAlias: String,
        val userIdColumn: String,
        val orgIdColumn: String,
    )

/**
 * 选择类型
 * @author tangli
 * @date 2025/09/19 09:46
 */
public enum class SelectionType {
    INCLUDE,
    EXCLUDE,
}

/**
 * 表名类型
 * @author tangli
 * @date 2025/09/19 09:46
 */
public enum class TableNameType {
    TABLE,
    ALIAS,
}
